#pragma once

#include <string>
#include <exception>
#include "spdlog/spdlog.h"
#include "common/format.h"


namespace evm {

#define log_debug(...) evm::LOG->debug(__VA_ARGS__) << " [" << __FILE__ << ":" << __LINE__ << ", " << __func__ << "]"
#define log_info(...) evm::LOG->info(__VA_ARGS__) << " [" << __FILE__ << ":" << __LINE__ << ", " << __func__ << "]"
#define log_warn(...) evm::LOG->warn(__VA_ARGS__) << " [" << __FILE__ << ":" << __LINE__ << ", " << __func__ << "]"
#define log_error(...) evm::LOG->error(__VA_ARGS__) << " [" << __FILE__ << ":" << __LINE__ << ", " << __func__ << "]"

extern std::shared_ptr<spdlog::logger> LOG;

void init_log(std::string file_name = "evm", bool to_file = true, bool to_stdout = false);

template <typename... Args>
void throw_with_log(const char* fmt, Args... args) {
    std::string msg = fmt::format(fmt, args...);
    LOG->error() << msg;
    throw std::runtime_error(msg);
}

template <typename... Args>
void throw_with_log(const std::string& fmt, Args... args) {
    throw_with_log(fmt.data(), args...);
}

}
